#include "gtx31x_api.h"
#include "gtx31x_iic.h"

#if _KEYBOARD_FUNCTION_ENABLE_

uint8_t Gtx31xGetChipId(void)
{
  return Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_HARDWAREATTR);
}

uint16_t Gtx31xGetTouchDetectionBit(void)
{
  uint16_t TouchKeyValue = 0;

  TouchKeyValue = Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_TOUCH_OUTPUT_2);
  TouchKeyValue = (TouchKeyValue & 0x0F) << 8;
  TouchKeyValue |= Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_TOUCH_OUTPUT_1);

  return TouchKeyValue;
}

void Gtx31xSetEachOfChannelContorlBit(uint8_t Channel, bool ControlEn)
{
  uint8_t RegValue = 0;
  uint16_t RegChannelValue = 0, NewChannelValue = 0;

  if (Channel != GTX31X_CHAEENL_BIT_ALL)
  {
    RegChannelValue = Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_SIN_CH_EN_2);
    RegChannelValue <<= 8;
    RegChannelValue |= Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_SIN_CH_EN_1);

    if (ControlEn == true)
    {
      NewChannelValue = 1 << Channel;
      RegChannelValue = RegChannelValue | NewChannelValue;
    }
    else
    {
      NewChannelValue = (uint16_t)(~(1 << Channel));
      RegChannelValue = RegChannelValue & NewChannelValue;
    }
  }
  else
  {
    RegChannelValue = (ControlEn == true) ? 0x3FFF : 0x3000;
  }

  RegValue = (uint8_t)((RegChannelValue & 0xFF00) >> 8);
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_SIN_CH_EN_2, RegValue);
  RegValue = (uint8_t)(RegChannelValue & 0x00FF);
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_SIN_CH_EN_1, RegValue);
}

void Gtx31xSoftwareReset(bool En)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_RESET_CONTORL, 0x30 | En);
}

void Gtx31xSetSleepMode(bool En)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_SLEEP_CONTORL, En);
}

uint8_t Gtx31xGetSleepRegister(void)
{
  return Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_SLEEP_CONTORL);
}

void Gtx31xSetPullUpContorlBit(bool ContorEn)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_IIC_PU_CONTROL, ContorEn);
}

void Gtx31xSetInterruptOperationMode(uint8_t Mode)
{
  uint8_t RegValue = 0;

  RegValue = Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_CTTL_BIT_0);
  RegValue = (Mode == GTX31X_SINGLE_TOUCH_MODE) ? (RegValue & 0xEF) : (RegValue | 0x10);
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_CTTL_BIT_0, RegValue);
}

void Gtx31xSetTouchEngineMode(uint8_t Mode)
{
  uint8_t RegValue = 0;

  RegValue = Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_CTTL_BIT_0);
  RegValue = (Mode == GTX31X_PULSE_MODE) ? (RegValue & 0xFE) : (RegValue | 0x01);
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_CTTL_BIT_0, RegValue);
}

void Gtx31xSetTouchExpireMode(uint8_t Time, uint8_t Enable, uint8_t Mode)
{
  uint8_t RegValue = 0;

  RegValue = ((Time << 4) | (Enable << 1)) | Mode;
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_CTRL_BIT_1, RegValue);
}

void Gtx31xSetCalibrationTime(uint8_t Time)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_CAL_TIME, Time);
}

void Gtx31xSetSensorIdleTime(uint8_t Time_H, uint8_t Time_L)
{
  uint8_t RegisterValue = 0, SetErrorCount = GTX31X_GET_REGISTER_FAILURE_TIMES;

  while (SetErrorCount--)
  {
    Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_SEN_IDLE_TIME, Time_H);
    Gtx31xDelayMs(1);

    RegisterValue = Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_SEN_IDLE_TIME);
    if (RegisterValue == Time_H)
      break;
  }

  RegisterValue = 0;
  SetErrorCount = GTX31X_GET_REGISTER_FAILURE_TIMES;

  while (SetErrorCount--)
  {
    Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_SEN_IDLE_TIME_SUFFIX, Time_L);
    Gtx31xDelayMs(1); 

    RegisterValue = Gtx31xIicReadOneByte(GTX31X_IIC_ADDRESS, GTX31X_SEN_IDLE_TIME_SUFFIX);
    if (RegisterValue == Time_L)
      break;
  }
}

void GtxSetBuysToIdleTime(uint8_t Time)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_BUSY_TO_IDLE_TIME, Time);
}

void Gtx31xIdleToBusyContorlBit(uint8_t En)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_I2B_MODE, En);
}

void Gtx31xSlideModeEnableBit(uint8_t En)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, GTX31X_SLIDE_MODE, En);
}

void Gt312SetTouchSensitivityControlBit(uint8_t Channel, uint8_t Value)
{
  uint8_t TouchChannel = 0;

  TouchChannel = GTX31X_SENSITIVITY + Channel;
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, TouchChannel, Value);
}

void Gtx31xWriteSpecialRegister(uint8_t Register, uint8_t Value)
{
  Gtx31xIicWriteOneByte(GTX31X_IIC_ADDRESS, Register, Value);
}

#endif
